/** @jsxImportSource @emotion/react */
//import { jsx } from "@emotion/react";
import * as React from "react";
import {
    List,
    ListItem,
    Avatar,
    IconButton,
    Button,
    MenuList,
    useTheme,
    IconMoreVertical,
    Skeleton,
    MenuItem,
    IconPackage,
    IconRefButton,
    useToast,
    Touchable,
    Text,
    IconChevronRight, PanelEnlargeCtx, VerticalMenu, DdMenuItem,
} from "customize-easy-ui-component";

//import {  usePaginateQueryDevice,  } from "./db";
import { Link as RouterLink } from "../routing/Link";
import {useContext, useEffect, useRef} from "react";
import { useInView } from 'react-intersection-observer'
import RoutingContext from "../routing/RoutingContext";
import {usePaginationFragment, useRefetchableFragment} from "react-relay/hooks";
import {DeviceListInner$key} from "./__generated__/DeviceListInner.graphql";
import {VariablesOf} from "relay-runtime";
import {useChangeValue} from "../hooks/useHelpers";
import {businessCatspMap, taskStatusMap} from "../task/TaskList";
import {eqpTypeAllMap} from "../dict/eqpComm";
import {eqpUseStateMap} from "../pipeline/edit/管道单元";
//import { PullToRefresh,PullDownContent,RefreshContent,ReleaseContent } from "react-js-pull-to-refresh";
//import { usePrevious } from "customize-easy-ui-component/esm/Hooks/previous";
const graphql = require("babel-plugin-relay/macro");

interface DeviceListInnerProps {
    eqps: DeviceListInner$key;
    //常规过滤器设置参数，通过路由器和sessionStorage存储的。
    filter: any   //用props参数看看
    //特殊的简易搜索框输入的参数做过滤的，作用范围较为短暂,不通过路由器sessionStorage，只会在当前mount组件的状态变量进行传递的。
    query: string     //还是把简易搜索输入框的内容传递下去
}
export const DeviceListInner: React.FunctionComponent<
  DeviceListInnerProps
> = (props: DeviceListInnerProps) => {
  const theme = useTheme();
  const { history } = useContext(RoutingContext);
    const toast = useToast();
  //useRefetchableFragment不能用在普通对象模型上;
  //提取查询到路由器loadMore　,refetch  devicesFind, loading 参数{filter}
    //很特殊的！ DeviceListInnerRefetchQuery 直接作为入口，没有前面的查询可嵌套的,Query直接套上.
    //要用usePaginationFragment必须上connection应答类型，接口须有first或last参数的,
    //上级usePreloaded定义了参数after，下级fragment就不再要定义@argumentDefinitions(after: )参数了。
    //参数@argumentDefinitions( #states: { type: "[IssueState!]", defaultValue: OPEN })
    //参数若是只放在这一层定义而上级那层没定义的将会导致自动生成文件接口定义没有这里的参数，所以失败啊。
    //@argumentDefinitions()里面参数多定义了没用到也不会报错的。 loadNext(,UNSTABLE_extraVariables)
    //这里@argumentDefinitions()里不能和上层次共同定义一个同名字参数的，编译报错。
    //参数若仅在这里定义而上层没有定义，导致主查询提前装载数据失败，Refetch才会有该参数，重新查询能查询正常，奇异！非要点击refetch才能获得正常数据那还叫提前装载,refetch等于loadQuery(var)。
  //隐含【BUG】发现Relay毛病 loadQuery和usePreloadedQuery的参数不一致可能导致@refetchable(queryName)获得列表无法被loadQuery再次加载读的数据替换，依然保留refetch所提取旧的列表。强制刷新路由。
  const { data, refetch , loadNext,hasNext,isLoadingNext} = usePaginationFragment(
      graphql`
        fragment DeviceListInner on Query
        @refetchable(queryName: "DeviceListInnerRefetchQuery") {
            getAllEqpEsFilter(where: $where,after:$after,first:$first,orderBy:$orderBy,asc:$asc)
          @connection(key: "Query_getAllEqpEsFilter") {
              edges {
                  __id
                  node {
                      id cod oid type sort vart ust reg
                       plno address useu{id name}
                  }
              }
          }
        }
      `,
      props.eqps,
  );
  const {getAllEqpEsFilter }=data;
    const devicesFind=getAllEqpEsFilter?.edges;

  /*
  const { data,refetch, hasNext, loadNext, isLoadingNext } = usePaginationFragment(
      graphql`
        fragment IssueDetailComments_issue on Issue
        @argumentDefinitions(
          cursor: { type: "String" }
          count: { type: "Int", defaultValue: 10 }
        )
        @refetchable(queryName: "IssueDetailCommentsQuery") {
          comments(after: $cursor, first: $count)
        }
      `,
      props.issue,
  );
  */

    const queryRef =useRef('');       //初始化值必须和输入组件query的一样！否则底下queryChanged逻辑变导致多次触发refetch();
  //上面这个副作用必须 加usersFind，否则无法继续处理后端数据带来的必要的UI反馈变化。
  const refLsize = React.useRef(0);
  const [refMore, acrossMore] = useInView({threshold: 0});
  //后端返回了loading变动=会更新整个DeviceList组件，同时也执行updateQuery: ()=>{}回调更新数据。
    //     offset: devicesFind.length,
  /*const toLoadMore = React.useCallback(
    async () => {
      refLsize.current=devicesFind?.length || 0;    //看看有没有新增加项目
      devicesFind && loadNext(3);
    },
    [loadNext ,devicesFind]
  );*/


  //   todo:暂时屏蔽！
  // useEffect( () => { acrossMore && hasNext
  //             &&  loadNext(8,{
  //                     onComplete: (error) =>  {
  //                         if(error){
  //                             console.log("列表报错 data=", data );
  //                             toast({
  //                                 title: "返回了",
  //                                 subtitle: ""+error,
  //                                 intent: "error"
  //                             });
  //                         }
  //                     }
  //                 });
  //         },
  //       [acrossMore, hasNext,loadNext]);


    //界面没提供命令入口点
    //列表上面的世界搜索框和列表实际算兄弟组件，上边的组件修改输入过滤，下边组件要依照兄弟组件修改后的参数重新做一次查询更新。传递值，不传递操作函数。
    //编辑框输入的过滤参数模式和这一单个简易搜索Box的方式都是过滤操作，这两个的触发冲突？显示。
  // const callRefetch = React.useCallback(() => {
  //       //setHasMore(true);
  //     console.log("霉R1变 准备再查询 filter=",props.filter);
  //      // refetch( filter );   todo: 暂时改成这样的  {fetchPolicy: 'store-or-network'}
  //     refetch({...props.filter}, {fetchPolicy: 'network-only'})
  // }, [refetch, props.filter]);

    //【依赖】底下若是refetch加入依赖项，导致多一次更新，这次更新props.filter还是旧的。组件先更新refetch然而props.filter还未切换为最新的，所以获取旧参数！
    //【重复更新】修改路由可知参数的，组件经过路由器已经修改数据；所以底下的第一次props.filter变动应当忽视掉，避免重复去后端刷新数据。useEffect不能替代点击触发机制。
    //当前页面仅仅路由切换state{}并不会导致本组件的卸载后再次装载，所以取值很可能是上一次遗留的；简易搜索框pk过滤器对话框的两个场景？两种渠道更新查询不能共存？混杂不行;
    React.useEffect(() => {
        //【避免重复】触发refetch(),这里的参数构造结果应该和路由器入口构造结果保证一致。否则就会发生两次查询。DeviceMainQuery有可能不止于一个DeviceListInnerRefetchQuery查询组件，可能多个组件一次性放在一个graphQL发送包一起发给后端的。
        let filtercomp={where: {cod: props.query===""?undefined:props.query, ...props.filter.where},
            offset:0,
            first:3,
            asc: props.filter.asc
        };
        let queryChanged= false;
        if(queryRef.current !== props.query){
            queryRef.current = props.query as any;
            queryChanged= true;
        }
        //使用useEffect的缺陷：若cod="",无法切换回去，必须知道cod前面一次赋值来对比。
        if(queryChanged || JSON.stringify(props.filter) !== JSON.stringify(filtercomp) ) {
            console.log("JY每次都要的发起更新@=",refetch,"filter=",filtercomp);
            refetch(filtercomp, {fetchPolicy: 'network-only'});      //尽量避免路由器myQuery: loadQuery(vars)里面有两个以上的查询，多个查询有各自的参数名字空间，需要独立分离参数，filter的多参数拆分独立。
        }
    }, [props.query, props.filter, refetch]);

  //【有问题】refetch这个时间的入口参数filter还是捕获的旧的，须延迟一个render()后再去做。
/*  React.useEffect(() => {
    console.log("两次倒腾callRefetch重做 可能旧filter=",props.filter);
    callRefetch();
  }, [callRefetch]);*/

    const {save, field, reurl, p1field, multi}= window.history.state?.state??{};      //通用伪对话框传递格式
    console.log("最近devicesFind队列长度=",devicesFind?.length,"filter=",props.filter);
    const {enlarge, setEnlarge,setActivecas} =useContext(PanelEnlargeCtx);
  //控件<Stack 是堆叠式的，像导航条；适用同一个模板显示只需上级给下级参数调整的场景。根据上一叠页面选择触发状态relation给下一叠参数来控制下一级显示；更多嵌套很困难。
  return (
    <React.Fragment>
            <List className="DlistInner">
              {isLoadingNext && (
                <React.Fragment>
                  <ListItem
                    interactive={false}
                    contentBefore={
                      <Skeleton
                        css={{
                          width: "32px",
                          height: "32px",
                          borderRadius: "50%"
                        }}
                      />
                    }
                    primary={<Skeleton css={{ maxWidth: "160px" }} />}
                  />
                  <ListItem
                    interactive={false}
                    contentBefore={
                      <Skeleton
                        css={{
                          width: "32px",
                          height: "32px",
                          borderRadius: "50%"
                        }}
                      />
                    }
                    primary={<Skeleton css={{ maxWidth: "200px" }} />}
                  />
                </React.Fragment>
              )}

                {devicesFind?.map((hit,i) => {
                    const dev= hit?.node!;
                    const usueName= dev.useu?.name;
                    const sonLine = (
                        <Text variant="h6" gutter={false}>
                            { usueName+" "+dev?.plno }
                        </Text>
                    );
                    return (
                        <ListItem
                            key={dev?.id}
                            interactive={ true}
                           onPress={(e) => {
                               history.push(`/device/${dev?.id}`, {save,field,reurl,p1field,multi});
                               setActivecas(0);
                               // e?.stopPropagation();
                           }}
                           primary={`${dev.cod} ${eqpTypeAllMap.get(dev?.vart!)} ${eqpUseStateMap.get(dev?.ust!)}`}
                            secondary={`${dev.oid} ${dev.address}`}
                               contentAfter={
                                   <VerticalMenu>
                                       <DdMenuItem label="加个设备"
                                                   onClick={(e) => {
                                                       history.push("/device/new");
                                                   }}/>
                                       <DdMenuItem label="功能待续"
                                                   onClick={(e) => {
                                                   }}/>
                                   </VerticalMenu>
                               }
                        >
                            { sonLine }
                        </ListItem>
                    );
                })}

            </List>

              <div
                css={{
                  textAlign: "center",
                  marginBottom: theme.spaces.md,
                  marginTop: theme.spaces.md
                }}
              >
                { hasNext &&  (
                  <div>
                    <Button disabled={isLoadingNext}
                            onPress={async (e) => {
                                e?.stopPropagation();
                                await loadNext(27,{
                                    onComplete: (error) =>  {
                                        if(error){
                                            toast({
                                                title: "返回了",
                                                subtitle: ""+error,
                                                intent: "error"
                                            });
                                        }
                                    }
                                });
                            } }
                            >
                      按，拉扯获取更多......
                    </Button>
                  </div>
                )}
                {(refLsize.current===devicesFind?.length)  &&　<React.Fragment>
                      <span>嘿，没有更多了</span>
                  </React.Fragment>
                }
              </div>
              {/*<div  ref={refMore}  css={{height: "1px"}}> </div>*/}
    </React.Fragment>
  );
};

